package com.example.container;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class XmlBeanFactory implements BeanFactory {
    private Map<String, BeanDefinition> beanDefinitions = new HashMap<>();
    private Map<String, Object> singletonBeans = new HashMap<>();

    public XmlBeanFactory(String configLocation) {
        loadBeanDefinitions(configLocation);
    }

    private void loadBeanDefinitions(String configLocation) {
        try {
            // 解析XML配置文件
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(configLocation);
            Document document = builder.parse(inputStream);

            // 处理所有bean节点
            NodeList beanNodes = document.getElementsByTagName("bean");
            for (int i = 0; i < beanNodes.getLength(); i++) {
                Node beanNode = beanNodes.item(i);
                if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element beanElement = (Element) beanNode;
                    String id = beanElement.getAttribute("id");
                    String className = beanElement.getAttribute("class");

                    BeanDefinition beanDefinition = new BeanDefinition(id, className);

                    // 处理属性
                    NodeList propertyNodes = beanElement.getElementsByTagName("property");
                    for (int j = 0; j < propertyNodes.getLength(); j++) {
                        Node propertyNode = propertyNodes.item(j);
                        if (propertyNode.getNodeType() == Node.ELEMENT_NODE) {
                            Element propertyElement = (Element) propertyNode;
                            String name = propertyElement.getAttribute("name");
                            String value = propertyElement.getAttribute("value");
                            beanDefinition.addProperty(name, value);
                        }
                    }

                    beanDefinitions.put(id, beanDefinition);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("加载Bean定义失败", e);
        }
    }

    @Override
    public Object getBean(String beanId) throws Exception {
        // 先从缓存中获取
        if (singletonBeans.containsKey(beanId)) {
            return singletonBeans.get(beanId);
        }

        // 获取Bean定义
        BeanDefinition beanDefinition = beanDefinitions.get(beanId);
        if (beanDefinition == null) {
            throw new Exception("没有找到Bean定义: " + beanId);
        }

        // 反射创建Bean实例
        Class<?> beanClass = Class.forName(beanDefinition.getClassName());
        Object bean = beanClass.newInstance();

        // 设置属性
        Map<String, String> properties = beanDefinition.getProperties();
        for (Map.Entry<String, String> entry : properties.entrySet()) {
            String propertyName = entry.getKey();
            String propertyValue = entry.getValue();

            // 使用反射设置字段值
            Field field = beanClass.getDeclaredField(propertyName);
            field.setAccessible(true);

            // 根据字段类型转换值
            Class<?> fieldType = field.getType();
            if (fieldType == String.class) {
                field.set(bean, propertyValue);
            } else if (fieldType == int.class || fieldType == Integer.class) {
                field.set(bean, Integer.parseInt(propertyValue));
            } else if (fieldType == double.class || fieldType == Double.class) {
                field.set(bean, Double.parseDouble(propertyValue));
            }
            // 可以扩展更多类型
        }

        // 放入缓存
        singletonBeans.put(beanId, bean);

        return bean;
    }
}
